﻿// $Id: RuleAttribute.cs 10 2008-02-29 15:58:02Z mcartoixa $

/* ***************************************************************************
 *                                                                           *
 * Copyright © 2007 NourY Solutions                                          *
 *                                                                           *
 * This file is part of DataRules.                                           *
 *                                                                           *
 * DataRules is free software; you can redistribute it and/or modify it      *
 * under the terms of the GNU Lesser General Public License as published     *
 * by the Free Software Foundation; either version 3 of the License, or      *
 * (at your option) any later version.                                       *
 *                                                                           *
 * DataRules is distributed in the hope that it will be useful, but          *
 * WITHOUT ANY WARRANTY; without even the implied warranty of                *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU          *
 * Lesser General Public License for more details.                           *
 *                                                                           *
 * You should have received a copy of the GNU Lesser General Public          *
 * License along with this program.  If not, see                             *
 * <http://www.gnu.org/licenses/lgpl.html>.                                  *
 *                                                                           *
 *************************************************************************** */

/*! \file
 * \brief Definition of \c Salamanca.DataRules.RuleAttribute.
 *
 * \author $Author: mcartoixa $
 * \date $Date: 2008-02-29 16:58:02 +0100 (ven., 29 févr. 2008) $
 * \version $Revision: 10 $
 */

using System;
using System.Diagnostics;
using System.Globalization;

namespace Salamanca.DataRules
{



    ///////////////////////////////////////////////////////////////////////////
    ///
    /// <summary>Basic business rule attribute implementation.</summary>
    /// <remarks>
    ///   <example>
    ///     <code>
    /// [AttributeUsage(AttributeTargets.Property, Inherited=true, AllowMultiple=false)]
    /// public sealed class NotNullRuleAttribute:
    ///     RuleAttribute
    /// {
    ///
    ///     /// <summary>Constructor.</summary>
    ///     public NotNullRuleAttribute():
    ///         base(typeof(NotNullRule&lt;&gt;))
    ///     {
    ///     }
    ///
    /// }
    ///     </code>
    ///   </example>
    /// </remarks>
    ///
    ///////////////////////////////////////////////////////////////////////////

    [AttributeUsage(AttributeTargets.Property, Inherited=true, AllowMultiple=true)]
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", Justification="ruleType is not an attribute argument for derived classes")]
    public abstract class RuleAttribute:
        Attribute
    {

        /// <summary>Constructor.</summary>
        private RuleAttribute()
        {
        }

        /// <summary>Constructor.</summary>
        /// <param name="ruleType">The type of the rule that applies to the property.</param>
        /// <exception cref="ArgumentException">
        ///   <para><paramref name="ruleType" /> is not a type that implements <see cref="IRule" />.</para>
        /// </exception>
        protected RuleAttribute(Type ruleType)
        {
            Debug.Assert(ruleType!=null);
            if (ruleType==null)
                throw new ArgumentNullException("ruleType");

#if (!NET_CF)
            bool isValidType=ruleType.GetInterface(typeof(IRule).FullName)!=null;
#else

            Type[] interfaces=ruleType.GetInterfaces();
            System.Array.Sort<Type>(interfaces);
            bool isValidType=System.Array.BinarySearch<Type>(interfaces, typeof(IRule))>=0;
#endif
            Debug.Assert(isValidType);
            if (!isValidType)
                throw new ArgumentException(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        Resources.SR.InvalidRuleTypeException,
                        ruleType,
                        typeof(IRule)
                    )
                );
        }

        /// <summary>Gets the rule associated with the attribute.</summary>
        public abstract IRule GetRule(Type targetType, string propertyName);

        /// <summary>The description of the rule.</summary>
        public string Description
        {
            get
            {
                return _Description;
            }
            set
            {
                _Description=value;
            }
        }

        /// <summary>The description of the rule.</summary>
        private string _Description=string.Empty;

    }

}
